using System;
using SVM;

namespace MLSharp.SupportVectorMachines
{
	/// <summary>
	/// The options to use when training LibSVM classifiers.
	/// </summary>
	public class LibSvmExOptions : Parameter
	{
		#region Private Readonly Fields

		/// <summary>
		/// Maps <see cref="SvmType"/>s back to their numerical
		/// values for svm-predict and svm-train.
		/// </summary>
		private static readonly SvmType[] mSvmTypeMap = new[]
            	{
					SvmType.C_SVC,
					SvmType.NU_SVC,
					SvmType.ONE_CLASS,
					SvmType.EPSILON_SVR,
					SvmType.NU_SVR
            	};

		/// <summary>
		/// Maps <see cref="KernelType"/>s back to their numerical
		/// values for svm-predict and svm-train.
		/// </summary>
		private static readonly KernelType[] mKernelTypeMap = new[]
              	{
					KernelType.LINEAR,
					KernelType.POLY,
					KernelType.RBF,
					KernelType.SIGMOID,
					KernelType.PRECOMPUTED
              	};

		#endregion

		#region Private Methods

		/// <summary>
		/// Maps the selected SVM type to the number expected by svm-predict
		/// and svm-train.
		/// </summary>
		/// <returns></returns>
		private int GetSvmType()
		{
			return Array.IndexOf(mSvmTypeMap, SvmType);
		}

		/// <summary>
		/// Maps the selected kernel type to the number expected by 
		/// svm-predict and svm-train.
		/// </summary>
		/// <returns></returns>
		private int GetKernelType()
		{
			return Array.IndexOf(mKernelTypeMap, KernelType);
		}

		#endregion

		#region Public Overrides

		/// <summary>
		/// Returns a string that can be used to train a model
		/// with the currently selected options.
		/// </summary>
		/// <returns></returns>
		public override string ToString()
		{
			//Probability is not used; it must be set to 1, otherwise we won't be able
			//to parse the results.
			return string.Format("-s {0} -t {1} -d {2} {3}-r {4} -c {5} -n {6} -p {7} -b 1",
			                     GetSvmType(),
			                     GetKernelType(),
			                     Degree,
			                     Gamma > 0 ? "-g " + Gamma + " " : "",
			                     Coefficient0,
			                     C,
			                     Nu,
			                     EPS);
		}

		#endregion
	}
}